{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit Messaging;

interface

uses Windows;

const
  HELPER_SHUTDOWN_MESSAGE = '@home media - mediate helper shutdown message';
  MANAGER_SHUTDOWN_MESSAGE = '@home media - mediate media manager shutdown message';
  MEDIATE_SHUTDOWN_MESSAGE = '@home media - mediate client shutdown message';
  MEDIATE_LAUNCH_MESSAGE = '@home media - mediate client launch message';
  MEDIATE_REMOTE_MESSAGE = '@home media - mediate remote control message';
  MEDIATE_CONFIG_MESSAGE = '@home media - mediate configuration message';

type
  // Known message types for mediate application suite
  TAHMMessageType = (mtUnknown, mtHelperShutdown, mtManagerShutdown,
                     mtMediateShutdown, mtMediateLaunch, mtMediateRemote,
                     mtMediateConfigure);

  TAHMMessenger = class
  private
    FHelperShutdownMessage: Cardinal;
    FManagerShutdownMessage: Cardinal;
    FMediateShutdownMessage: Cardinal;
    FMediateLaunchMessage: Cardinal;
    FMediateRemoteMessage: Cardinal;
    FMediateConfigureMessage: Cardinal;
  protected
    procedure RegisterMessages;
  public
    constructor Create;
    function HandleMessage(var Msg: TMsg; var Handled: Boolean): TAHMMessageType;
    procedure RequestHelperShutdown;
    procedure RequestManagerShutdown;
    procedure RequestMediateShutdown;
    procedure RequestMediateLaunch;
    procedure RequestMediateConfigure(Handle: HWND);
    procedure SendMediateRemoteCommand(KeyCode: Word);
  end;

var
  MessengerInstance: TAHMMessenger;

implementation

constructor TAHMMessenger.Create;
begin
  inherited Create;

  RegisterMessages;
end;

procedure TAHMMessenger.RegisterMessages;
begin
  // Register custom windows messages
  FHelperShutdownMessage := RegisterWindowMessage(HELPER_SHUTDOWN_MESSAGE);
  FManagerShutdownMessage := RegisterWindowMessage(MANAGER_SHUTDOWN_MESSAGE);
  FMediateShutdownMessage := RegisterWindowMessage(MEDIATE_SHUTDOWN_MESSAGE);
  FMediateLaunchMessage := RegisterWindowMessage(MEDIATE_LAUNCH_MESSAGE);
  FMediateRemoteMessage := RegisterWindowMessage(MEDIATE_REMOTE_MESSAGE);
  FMediateConfigureMessage := RegisterWindowMessage(MEDIATE_CONFIG_MESSAGE);
end;

function TAHMMessenger.HandleMessage(var Msg: TMsg; var Handled: Boolean): TAHMMessageType;
begin
  // This method needs to be very performant as it is called on receipt of EVERY message
  if Msg.message = FHelperShutdownMessage then Result := mtHelperShutdown
  else if Msg.message = FManagerShutdownMessage then Result := mtManagerShutdown
  else if Msg.message = FMediateShutdownMessage then Result := mtMediateShutdown
  else if Msg.message = FMediateLaunchMessage then Result := mtMediateLaunch
  else if Msg.message = FMediateRemoteMessage then Result := mtMediateRemote
  else if Msg.message = FMediateConfigureMessage then Result := mtMediateConfigure
  else Result := mtUnknown;

  // If it's a known message type then indicate that we have handled it
  if Result <> mtUnknown then Handled := True;
end;

procedure TAHMMessenger.RequestHelperShutdown;
begin
  BroadcastSystemMessage(BSF_POSTMESSAGE, nil, FHelperShutdownMessage, 0, 0);
end;

procedure TAHMMessenger.RequestManagerShutdown;
begin
  BroadcastSystemMessage(BSF_POSTMESSAGE, nil, FManagerShutdownMessage, 0, 0);
end;

procedure TAHMMessenger.RequestMediateShutdown;
begin
  BroadcastSystemMessage(BSF_POSTMESSAGE, nil, FMediateShutdownMessage, 0, 0);
end;

procedure TAHMMessenger.RequestMediateLaunch;
begin
  BroadcastSystemMessage(BSF_POSTMESSAGE, nil, FMediateLaunchMessage, 0, 0);
end;

procedure TAHMMessenger.RequestMediateConfigure(Handle: HWND);
begin
  PostMessage(Handle, FMediateConfigureMessage, 0, 0);
end;

procedure TAHMMessenger.SendMediateRemoteCommand(KeyCode: Word);
var
  Recipients: DWORD;
begin
  Recipients := BSM_APPLICATIONS;
  BroadcastSystemMessage(BSF_POSTMESSAGE, @Recipients, FMediateRemoteMessage, KeyCode, 0);
end;


initialization
  // Create messenger instance
  MessengerInstance := TAHMMessenger.Create;

finalization
  // Release messenger instance
  MessengerInstance.Free;

end.
